"use strict"

module.exports = function(app, db, options){
  var _ = require("lodash"),
      AccessToken = require("../utils/AccessToken"),
      debug = require('debug')('qywx-api'),
  		express = require('express'),
      template = require("es6-template-strings"),
  		util = require('util'),
      path = require('path'),
      jwt = require('jsonwebtoken'),
      urlencode = require('urlencode'),
  		url = require('url'),
      rp = require("request-promise"),
      models = db;

  var router = express.Router();


  const QYWX_LOGINPAGE_REQUEST_URL = "https://qy.weixin.qq.com/cgi-bin/loginpage?corp_id=${corpId}"
                                      + "&redirect_uri=${redirectUri}&state=${state}&usertype=${userType}";
  const QYWX_GET_LOGIN_INFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_login_info?access_token=${accessToken}";


  router.get("/handler", function(req, res, next){
    var userType = req.query.usertype;
    var corpId = req.query.corp_id;
    var returnUrl = req.query.return_url; //the URL initial the login request, will redirect back after success auth
    var referer = req.get('Referrer');
    var parsedUrl = url.parse(req.originalUrl);

    /**
     * generate and save state
     */
    models.CorpWechatAuthRequest.generateState(
      corpId, userType, returnUrl, referer
    )
    .then(function(instance){
      var qywxAuthUrl = template(QYWX_LOGINPAGE_REQUEST_URL, {
        corpId: corpId,
        redirectUri: urlencode(
            url.format({
            protocol: req.protocol,
            host: req.header("host"),
            pathname: path.join(req.baseUrl, "callback")
          })
        ),
        userType: userType,
        state: instance.state
      })

      if(process.env.NODE_ENV === 'development'){
        return res.redirect(qywxAuthUrl)
      }else{
        return res.render("qywxAuth", { qywxAuthUrl: qywxAuthUrl });
      }
    })
    .catch(function(err){
      debug(err);
      return res.status(500).json({
        success: false,
        errMsg: "failed_to_save_auth_state"
      });
    });
  })

  router.get("/callback",function(req, res, next){
    /*
     * Get jwt token config from req.x_account_config
     */

    var accountConfigs = req.app.locals.accountConfigs;


    var authCode = req.query.auth_code;
    var expiresIn = req.query.expires_in;
    var state = req.query.state;

    /**
     * Use state to query the request initiate this auth process
     */
    models.CorpWechatAuthRequest.findOne({
        where: {
          state: state
        }
    })
    .then(function(instance){
      //Try to retriev access token
      var corpId = instance.corpId;
      var returnUrl = instance.returnUrl;

      if(!accountConfigs[corpId]){
          throw new Error("invalid_wechat_corp_id");
      }
      var accountConfig = accountConfigs[corpId];

      var corpSecret = accountConfig.secret;



      /*************************************************************
       * 	MIMIC WECHAT RESPONSE - FOR DEVELOPMENT ONLY
       *************************************************************/
      if(process.env.NODE_ENV === 'development'){
        var claims = {
          sub: 'testuserid',
          detail: {}
        };

        var signedToken = jwt.sign(claims, accountConfig.jwtAccessTokenSecret ,{
                                      algorithm: accountConfig.jwtAccessTokenAlgorithm
                                      ,expiresIn: accountConfig.jwtAccessTokenExpiresIn
                                  });

        var urlObject = url.parse(returnUrl, true);
        var queryObject = {};
        _.assign(queryObject, urlObject.query, { "x_bearer": signedToken });
        return res.redirect(url.format({
          protocol: urlObject.protocol,
          host: urlObject.host,
          pathname: urlObject.pathname,
          query: queryObject,
          hash: urlObject.hash
        }));
      }
      /*************************************************************
       * 	END OF MIMIC
       *************************************************************/


      //Use id and secret and code to exchange token
      AccessToken(corpId, corpSecret, models, false, function( err, token ){
        var userInfoRpOptions = {
            method: 'POST',
            uri: template(QYWX_GET_LOGIN_INFO_URL, { accessToken: token.token }),
            body: {
  	           "auth_code": authCode
  	        },
            json: true // Automatically parses the JSON string in the response
        };

        rp(userInfoRpOptions)
          .then(function(data){
            debug("wechat userinfo reponse:", data)

            if(data.errcode > 0){
              return res.status(500).json({
                success: false,
                errCode: data.errcode,
                errMsg: data.errmsg
              });
            }

            //Generate JWT token
            var claims = {
              sub: (data.usertype == 1 || data.usertype == 3) ? data.user_info.email : data.user_info.userid,
              detail: data,
              corpId: corpId
            };

            var signedToken = jwt.sign(claims, accountConfig.jwtAccessTokenSecret ,{
                                          algorithm: accountConfig.jwtAccessTokenAlgorithm
                                          ,expiresIn: accountConfig.jwtAccessTokenExpiresIn
                                      });

            var urlObject = url.parse(returnUrl, true);
            var queryObject = {};
            _.assign(queryObject, urlObject.query, { "x_bearer": signedToken });
            return res.redirect(url.format({
              protocol: urlObject.protocol,
              host: urlObject.host,
              pathname: urlObject.pathname,
              query: queryObject,
              hash: urlObject.hash
            }));
          })
          .catch(function(err){
            console.error(err);
            throw new Error("failed_to_request_wechat_api");
          })
      })
    })
    .catch(function(err){
      console.error(err);
      return res.status(500).json({
        success: false,
        errMsg: err.message,
      })
    })
  })

  // router.get('/',function(req,res,next){
  //   return res.render('index');
  //   if(process.env.NODE_ENV == 'development'){
  //     res.cookie("openid", '测试用户的OPENID', {
  //       expires: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
  //     })
  //     res.cookie("islogin", 'true', {
  //       expires: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
  //     })
  //     return res.render('index');
  //   }
  // })
  //
  // function SaveWechatUser(req){
  //   var city = '';
	// 	var province = '';
	// 	if (req.cookies.province) {
	// 		province = decodeURIComponent(req.cookies.province);
	// 	}
	// 	if (req.cookies.city) {
	// 		city = decodeURIComponent(req.cookies.city);
	// 	}
	// 	var nickname='';
	// 	if (req.cookies.nickname) {
	// 		nickname = decodeURIComponent(req.cookies.nickname);
	// 	}
	// 	models.wechatusers.upsert({
	// 		'openid':   req.cookies.openid,
	// 		'nickname': nickname,
	// 		'province': province,
	// 		'city':     city,
	// 		'cdate': Math.round(new Date().getTime() / 1000)
	// 	}).then(function(data) {
  //
	// 	}).catch(function(error) {
	// 		logger.error('插入微信用户：' + decodeURIComponent(req.cookies.nickname));
	// 		logger.error(error);
  //
	// 	});
  // }



  app.use("/auth", router);
}
